home *** CD-ROM | disk | FTP | other *** search
- #ifndef STANDALONE
- #include "global.h"
- #include "ctype.h"
- #ifdef MSDOS
- #include <dir.h>
- #include <dos.h>
- #else
- #include <time.h>
- #endif
- #ifndef _lint
- #define SKIP_HACK 1 /* a quick hack to get around a compiler warning */
- #endif
- #include "commands.h"
- #include "files.h"
- #include "mailbox.h"
- #include "usock.h"
- #include "pktdrvr.h"
- #include "color.h"
- #include "x.h"
- #ifdef SQL
- #include "sql.h"
- #endif
- #ifndef MSDOS
- #include "ftp.h"
- #include "session.h"
- #endif
- #endif
-
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: tutor.c,v 1.25 1997/08/19 01:19:22 root Exp root $";
- #endif
-
- struct world {
- int mode;
- char color;
- char colorblock;
- char last[2];
- char inescape;
- char ipconnect;
- char *subdir;
- char const *call;
- time_t starttime;
- int ischild;
- #ifndef STANDALONE
- struct mbx *m;
- #endif
- FILE *fp;
- FILE *out;
- char *Tutors[100];
- int maxselect;
- char *variables[10];
- long indexes[10];
- #ifdef old
- int socket[10];
- #else
- int *socket;
- #endif
- int user;
- int whichsocket;
- int background;
- int goback;
- int lostconnection;
- char Error[80];
- };
-
-
-
- #ifndef STANDALONE
- int Tutored = 0;
- static int inMbScriptHook = 0;
- extern int Stutor, Sinfo, Snews, Tutorlogins[];
- extern char Tcall[AXALEN], Icall[AXALEN], Ncall[AXALEN];
- #endif
-
- extern int sockblock (int s, int value);
-
- #ifdef TUTOR
- static void mycolorchange (struct world *here, const char *input, char *last);
- static void mytprintf (struct world *here, const char *str);
-
- #ifndef STANDALONE
- static void mygets (char *buf, int size, struct world *here);
- #else
- void mygets (char *buf, int size, struct world *here);
- #endif
-
- #ifdef SQL
- static void expand_buf (char *buf, struct world *here);
- #endif
-
- static char *nextarg (char *cp, long *i);
- static char *nextnum (char *cp, int defval, struct world *here, long *i);
- static long getnum (char *cp, int defval, struct world *here);
- static int scriptconn (int argc, char *argv[], void *p);
- static char *getnext (char *cp, char **put, struct world *here);
- static void process (struct world *here);
- static void buildmenu (struct world *here);
-
- #ifndef STANDALONE
- void tutorserv (const char *call, struct mbx *m, int mode, int color, int ip);
- #else
- void tutorserv (const char *call, int mode, int color, int ip);
- #endif
-
- static int scriptcmd (struct world *inherited, FILE * fp, const char *name);
-
- #ifndef STANDALONE
- int dombscript (int argc, char *argv[], void *p);
- int proxy (FILE * fp, const char *from);
- #endif
- #endif /* TUTOR */
-
-
- #ifdef TUTOR
-
- static void
- mycolorchange (struct world *here, const char *input, char *last)
- {
- if (here->color)
- (void) colorchange (input, last);
- }
-
-
-
- static void
- mytprintf (struct world *here, const char *str)
- {
- if (here->background && !here->whichsocket)
- return;
- if (!here->colorblock)
- tprintf (str);
- else if (colorprintf (&here->inescape, here->color, (const unsigned char *) str))
- here->last[0] = 0;
- }
- #endif
-
-
-
- char *
- skipwhite (char IFLINT(const) *cp)
- {
- while (*cp && (*cp == ' ' || *cp == '\t' || *cp == '\n'))
- cp++;
- return (cp); /*lint !e605 */
- }
-
-
-
- char *
- skipnonwhite (char IFLINT(const) *cp)
- {
- while (*cp && *cp != ' ' && *cp != '\t' && *cp != '\n')
- cp++;
- return (cp); /*lint !e605 */
- }
-
-
-
- void
- trimright (char *cp)
- {
- while (cp[strlen (cp) - 1] == ' ')
- cp[strlen (cp) - 1] = 0;
- }
-
-
-
- void
- trimrightCR (char *cp)
- {
- rip (cp);
- trimright (cp);
- strcat (cp, "\n");
- }
-
-
-
- #ifdef TUTOR
- #ifndef STANDALONE
- static int tutor_recvline (int s, char *buf, unsigned size);
-
-
- static int
- tutor_recvline (int s, char *buf, unsigned size)
- {
- char *origbuf = buf;
- int c, cnt = 0, opt, cl;
-
- usflush (Curproc->output);
-
- for ( ; ; ) {
- if (nullsocket (s)) {
- c = EOF;
- cnt = 0;
- break;
- }
- c = recvchar (s);
- if (c == EOF) {
- if (errno == EWOULDBLOCK)
- continue;
- break;
- }
- kwait (NULL);
- if (c == IAC) { /* Telnet command escape */
- if ((c = recvchar (s)) == EOF)
- break;
- if (c >= 250 && c < 255 && (opt = recvchar (s)) != EOF) {
- switch (c) {
- case SB:
- opt = recvchar (s);
- if (opt == EOF)
- break;
- cl = opt;
- c = recvchar (s);
- while ((c != EOF) && !(cl == IAC && c == SE)) {
- cl = c;
- c = recvchar (s);
- }
- break;
- case WILL:
- if (opt == TN_LINEMODE) {
- tprintf ("%c%c%c", IAC, DO, opt);
- tprintf ("%c%c%c%c%c%c%c", IAC, SB, TN_LINEMODE, 1, 1, IAC, SE);
- } else
- tprintf ("%c%c%c", IAC, DONT, opt);
- break;
- case WONT:
- tprintf ("%c%c%c", IAC, DONT, opt);
- break;
- case DO:
- tprintf ("%c%c%c", IAC, WONT, opt);
- break;
- case DONT:
- tprintf ("%c%c%c", IAC, WONT, opt);
- break;
- default:
- break;
- }
- usflush (Curproc->output);
- kwait (NULL);
- continue;
- }
- if (c != IAC && (c = recvchar (s)) == EOF)
- break;
- }
- *buf++ = (char) c;
- ++cnt;
- if (c == '\n')
- break;
- if ((unsigned) cnt == (size - 1)) {
- cnt = -2;
- break;
- }
- /* the following is a special case HACK for telnet logins */
- if (!strncmp (origbuf, "login: ", 7) || !strncmp (origbuf, "Password: ", 10))
- break;
- }
- if (c == EOF && cnt == 0)
- return -1;
- *buf = '\0';
- return cnt;
- }
-
-
-
- static void
- mygets (char *buf, int size, struct world *here)
- {
- if ((here->background && !here->whichsocket) || here->user < 0) {
- buf[0] = 0;
- return;
- }
- usflush (Curproc->output);
- #ifdef MBXTDISC
- /* Restart the inactivity timer */
- if (here->m != NULLMBX)
- start_timer (&here->m->tdisc);
- #endif
-
-
- if ((size = tutor_recvline (here->user ? here->user : Curproc->input, buf, (unsigned) size)) < 0) {
- if (here->user > 0) {
- here->socket[here->whichsocket] = here->user = -1;
- Curproc->output = here->socket[0];
- }
- buf[0] = 0;
- here->lostconnection = -1;
- }
- rip (buf);
- }
- #endif /* STANDALONE */
-
-
-
- static char *
- nextarg (char *cp, long *i)
- {
- cp = skipnonwhite (cp);
- cp = skipwhite (cp);
- *i = atol (cp);
- return (cp);
- }
-
-
-
- static char *
- nextnum (char *cp, int defval, struct world *here, long *i)
- {
- cp = skipnonwhite (cp);
- cp = skipwhite (cp);
- *i = getnum (cp, defval, here);
- return (cp);
- }
-
-
-
- static long
- getnum (char *cp, int defval, struct world *here)
- {
- long l = defval;
-
- switch (*cp) {
- case '~':
- if (tolower (cp[1]) == 'i') {
- l = here->indexes[cp[2] - '0'];
- break;
- }
- if (cp[1] >= '0' && cp[1] <= '9') {
- l = atol (here->variables[cp[1] - '0']);
- break;
- }
- break;
- case 0:
- break;
- default:
- l = atol (cp);
- break;
- }
- return l;
- }
-
-
-
- static char SCONFail[] = "SCRIPT connect failed: ";
- static char SCONFail2[] = "SCRIPT disconnect failed: ";
-
-
- /* open a network connection based upon information in the cc line.
- * m->user is set to the socket number.
- */
- static int
- scriptconn (int argc, char *argv[], void *p)
- {
- struct world *here;
- char sock[MAXSOCKSIZE];
- union sp sp;
- char ctype;
- struct iface *ifp;
- char digis[MAXDIGIS][AXALEN];
- char target[AXALEN];
- int ndigis, i;
-
- here = (struct world *) p;
- sp.p = sock;
- here->Error[0] = 0; /* null error string */
- ctype = (char) tolower (*argv[0]);
- if (argc < 2) {
- sprintf (here->Error, "%sSyntax Error", SCONFail);
- return -1;
- }
- switch (ctype) {
- #ifdef AX25
- case 'a':
- case 'c': /* allow 'c' for 'connect' as well */
- if (((ifp = if_lookup (argv[1])) == NULLIF) || (ifp->flags & HIDE_PORT)) {
- sprintf (here->Error, "%sUnknown port %s", SCONFail, argv[1]);
- return -1;
- }
- if (ifp->type != CL_AX25) {
- sprintf (here->Error, "%sPort %s not usable for AX.25 connects", SCONFail, argv[1]);
- return -1;
- }
- if (setcall (target, argv[2]) == -1) {
- sprintf (here->Error, "%sBad call %s", SCONFail, argv[2]);
- return -1;
- }
- /* If digipeaters are given, put them in the routing table */
- if (argc > 3) {
- ndigis = argc - 3;
- if (ndigis > MAXDIGIS) {
- sprintf (here->Error, "%sToo many digipeaters", SCONFail);
- return -1;
- }
- for (i = 0; i < ndigis; i++) {
- if (setcall (digis[i], argv[i + 3]) == -1) {
- sprintf (here->Error, "%sBad digipeater call %s", SCONFail, argv[i + 3]);
- return -1;
- }
- }
- if (ax_add (target, AX_AUTO, digis, ndigis, ifp) == NULLAXR) {
- sprintf (here->Error, "%sAX25 route add failed", SCONFail);
- return -1;
- }
- }
- sp.ax->sax_family = AF_AX25;
- strncpy (sp.ax->iface, argv[1], ILEN - 1); /* the interface name */
- (void) setcall (sp.ax->ax25_addr, argv[2]); /* the remote callsign */
- if ((here->user = socket (AF_AX25, SOCK_STREAM, 0)) == -1) {
- sprintf (here->Error, "%sError allocating socket", SCONFail);
- return -1;
- }
- break;
- #endif
- default:
- sp.in->sin_family = AF_INET;
- if ((sp.in->sin_addr.s_addr = resolve (argv[1])) == 0) {
- sprintf (here->Error, "%sHost Unknown", SCONFail);
- return -1;
- }
- /* get the optional port number */
- if (argc > 2)
- sp.in->sin_port = (int16) atoip (argv[2]);
- else
- sp.in->sin_port = IPPORT_TELNET;
- if ((here->user = socket (AF_INET, SOCK_STREAM, 0)) == -1) {
- sprintf (here->Error, "%sError allocating socket", SCONFail);
- return -1;
- }
- }
-
- (void) sockmode (here->user, SOCK_ASCII);
-
- if (connect (here->user, sp.p, SOCKSIZE) == -1) {
- sprintf (here->Error, "SCRIPT connect failed: %s errno %d",
- sockerr (here->user), errno);
- close_s (here->user);
- return -1;
- }
- return here->user;
- }
-
-
- static struct cmds sconcmds[] =
- {
- { "tcp", scriptconn, 0, 0, NULLCHAR },
- { "telnet", scriptconn, 0, 0, NULLCHAR },
- #ifdef AX25
- { "ax25", scriptconn, 0, 0, NULLCHAR },
- { "connect", scriptconn, 0, 0, NULLCHAR },
- #endif
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
-
-
- static char *
- getnext (char *cp, char **put, struct world *here)
- {
- char *retval = cp, buf[4], c;
- time_t tm;
-
- buf[1] = 0;
- if (*cp != '~') {
- buf[0] = *cp;
- *put = strdup (buf);
- } else {
- cp++;
- retval++;
- c = (char) tolower (*cp);
- (void) time (&tm);
- cp = ctime (&tm);
- rip (cp);
- cp[10] = cp[19] = 0;
- switch (c) {
- case 'l': /* elapsed time of script */
- *put = (char *) mallocw (20);
- sprintf (*put, "%-ld", (tm - here->starttime));
- break;
- case 'p': /* current data file position */
- *put = (char *) mallocw (20);
- if (here->out)
- sprintf (*put, "%-ld", ftell (here->out));
- else
- strcpy (*put, "-1");
- break;
- case 'c':
- *put = strdup (here->call);
- break;
- case 'e':
- *put = strdup (here->Error);
- break;
- case '~':
- case 'b':
- buf[0] = (c == 'b') ? '\007' : *retval;
- *put = strdup (buf);
- break;
- case 'h':
- *put = strdup (Hostname);
- break;
- case 'd':
- strcat (cp, ", ");
- strcat (cp, &cp[20]);
- *put = strdup (cp);
- break;
- case 't':
- *put = strdup (&cp[11]);
- break;
- case 'n':
- buf[0] = '\n';
- *put = strdup (buf);
- break;
- case 'u': /* un-terminate this line */
- rip (retval);
- buf[0] = *(++retval);
- *put = strdup (buf);
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (here->variables[c - '0'])
- *put = strdup (here->variables[c - '0']);
- else
- *put = strdup ("");
- break;
- case 'i':
- if (retval[1] >= '0' && retval[1] <= '9') {
- *put = (char *) mallocw (20);
- sprintf (*put, "%-ld", here->indexes[*(++retval) - '0']);
- break;
- }
- /* else fall through */
- default:
- sprintf (buf, "~%c", *retval);
- *put = strdup (buf);
- break;
- }
- }
- return (retval);
- }
-
-
-
- #ifdef SQL
- static void
- expand_buf (char *buf, struct world *here)
- {
- char *cp, *put;
- char newbuf[256];
-
- cp = buf;
- newbuf[0] = 0;
- while (*cp) {
- cp = getnext (cp, &put, here);
- strcat (newbuf, put);
- free (put);
- cp++;
- }
- strcpy (buf, newbuf);
- }
- #endif
-
-
-
- static void
- process (struct world *here)
- {
- FILE *fp;
- int done = 0, skipping = 0, k, disconexit = 1;
- long j, i, l;
- char buf[256], c, *cp, lastresponse = 'y', *label = 0;
- char *put, *replyto;
- long pos;
-
- (void) time (&here->starttime);
- if (!here->ischild) {
- #if 0
- for (k = 0; k < 10; k++) {
- here->variables[k] = 0;
- here->indexes[k] = 1;
- here->socket[k] = 0;
- }
- #endif
- } else {
- here->user = 0;
- disconexit = 0;
- }
-
- here->socket[0] = Curproc->output;
- #if 0
- if (here->user) { /* inherited a socket from a parent script! */
- Curproc->output = here->socket[1] = here->user;
- here->whichsocket = 1;
-
- Curproc->output = here->socket[here->whichsocket];
- disconexit = 0;
- }
- #endif
-
- while (!done && fgets (buf, 256, here->fp)) {
- #ifdef MBXTDISC
- /* Restart the inactivity timer */
- if (here->m != NULLMBX)
- start_timer (&here->m->tdisc);
- #endif
- kwait (NULL);
- if (buf[0] != '~' || ((buf[1] == '~') || isdigit (buf[1]))) {
- if (!skipping) {
- cp = buf;
- while (*cp) {
- cp = getnext (cp, &put, here);
- mytprintf (here, put);
- free (put);
- cp++;
- }
- }
- continue;
- }
- c = (char) tolower (buf[1]);
- cp = skipwhite (&buf[2]);
- rip (cp);
- if (skipping && c != 'l')
- continue;
- k = *cp - '0';
- if (k > 9)
- k = 0;
- switch (c) {
- case 'i': /* modify an index counter
- index array in k, already */
- cp++;
- rip (cp);
- cp = skipwhite (cp);
- c = *cp++;
- cp = skipwhite (cp);
- if (!strnicmp (cp, "~p", 2)) {
- if (here->out)
- l = ftell (here->out);
- else
- l = -1;
- } else
- l = getnum (cp, 1, here);
- switch (c) {
- case '=': /* assign */
- here->indexes[k] = l;
- break;
- case '+': /* add */
- here->indexes[k] += l;
- break;
- case '-': /* subtract */
- here->indexes[k] -= l;
- break;
- case '?': /* compare */
- c = lastresponse = (here->indexes[k] == l) ? 'y' : 'n';
- cp = skipnonwhite (cp);
- cp = skipwhite (cp);
- if (*cp && c == 'y')
- goto another;
- break;
- default:
- break;
- }
- break;
- another: case 'y': /* on yes, goto label *//*lint !e616 */
- case 'n': /* on no, goto label */
- if (lastresponse != c)
- break;
- case 'g': /* goto label *//*lint !e616 */
- skipping = 1;
- free (label);
- label = strdup (cp);
- rewind (here->fp);
- break;
- case 'l': /* label line */
- if (skipping && !stricmp (cp, label)) {
- free (label);
- label = 0;
- skipping = 0;
- }
- break;
- case 'b': /* output 'n' blank lines */
- k = (int) getnum (cp, 0, here);
- if (!k)
- k = 1;
- while (k--)
- mytprintf (here, "\n");
- break;
- case 'm': /* more prompt */
- mytprintf (here, "\n---MORE (*y/n)---\n");
- mygets (buf, 256, here);
- if (here->lostconnection)
- goto lost;
- kwait (NULL);
- if (tolower (buf[0]) != 'n')
- break;
- case 'x': /* exit at this point *//*lint !e616 */
- /* done = 1; */
- skipping = 1;
- free (label);
- label = strdup ("exit");
- break;
- case 'q': /* query with string for y/n answer */
- mytprintf (here, cp);
- mytprintf (here, " (*y/n)\n");
- mygets (buf, 256, here);
- if (here->lostconnection)
- goto lost;
- kwait (NULL);
- lastresponse = (tolower (buf[0]) == 'n') ? 'n' : 'y';
- break;
- case 'j': /* just compare first characters */
- case 'c': /* compare entire strings
- first string value in k, already */
- cp = nextarg (cp, &l);
- if (!here->variables[l] || !here->variables[k])
- lastresponse = 'n';
- else {
- if (c == 'c')
- c = lastresponse = (stricmp (here->variables[l], here->variables[k])) ? 'n' : 'y';
- else {
- cp = nextnum (cp, 0, here, &j);
- c = lastresponse = (strnicmp (here->variables[l], here->variables[k], (unsigned) j)) ? 'n' : 'y';
- }
- cp = skipnonwhite (cp);
- cp = skipwhite (cp);
- if (*cp && c == 'y')
- goto another;
- }
- break;
- case 'h': /* string has substring?
- first string value in k, already */
- cp = nextarg (cp, &l);
- if (!here->variables[l] || !here->variables[k])
- lastresponse = 'n';
- else {
- i = (int) strstr (here->variables[k], here->variables[l]);
- c = lastresponse = (!i) ? 'n' : 'y';
- if (i)
- i -= (int) here->variables[k];
- cp = nextarg (cp, &j);
- here->indexes[j] = i;
- cp = skipnonwhite (cp);
- cp = skipwhite (cp);
- if (*cp && c == 'y')
- goto another;
- }
- break;
- case 'p': /* pick out a sub-string
- to variable already in k */
- cp = nextarg (cp, &j); /* from variable */
- cp = nextnum (cp, 0, here, &i); /* start index */
- cp = nextnum (cp, 0, here, &l); /* length */
- if ((int) (strlen (here->variables[j]) - (unsigned long) i) < l)
- l = (long) (strlen (here->variables[j]) - (unsigned long) i);
- l++; /* allow room for zero byte */
- free (here->variables[k]);
- here->variables[k] = (char *) mallocw ((unsigned) l);
- strncpy (here->variables[k], &here->variables[j][i], (unsigned) l);
- here->variables[k][l - 1] = 0;
- break;
- case 't': /* truncate a variable string */
- cp = nextnum (cp, 0, here, &j);
- if ((int) strlen (here->variables[k]) > j)
- here->variables[k][j] = 0;
- break;
- case 'z': /* get length of variable and place in index */
- cp = nextarg (cp, &j);
- here->indexes[j] = (long) ((here->variables[k]) ? strlen (here->variables[k]) : 0);
- break;
- case 'a': /* assign a string to a variable */
- /* or append if 'ap str1 str2' */
- if ((cp == &buf[2]) && (tolower (*cp) == 'p')) {
- cp = skipwhite (++cp);
- if (*cp) {
- k = *cp - '0';
- cp = skipwhite (++cp);
- if (*cp) {
- l = *cp - '0';
- cp = (char *) mallocw (strlen (here->variables[k]) +
- strlen (here->variables[l]) + 1);
- strcpy (cp, here->variables[k]);
- strcat (cp, here->variables[l]);
- free (here->variables[k]);
- here->variables[k] = cp;
- }
- }
- break;
- } /* else fall through */
- case 'v': /* prompt and place result in variable */
- free (here->variables[k]);
- cp++;
- cp = skipwhite (cp);
- if (c == 'a') {
- if (*cp == '~')
- (void) getnext (cp, &here->variables[k], here);
- else
- here->variables[k] = strdup (cp);
- } else {
- if (*cp) {
- mytprintf (here, cp);
- mytprintf (here, "\n");
- }
- mygets (buf, 256, here);
- if (here->lostconnection)
- goto lost;
- kwait (NULL);
- here->variables[k] = strdup (buf);
- }
- break;
- case 'd': /* deliver a mail file */
- /* first check to see if this is a 'dr' command */
- replyto = NULLCHAR;
- if ((cp == &buf[2]) && (tolower (buf[2]) == 'r')) {
- /* this contains a reply-to string */
- cp = skipwhite (++cp);
- (void) getnext (cp, &replyto, here); /* allow ~c and ~# subs */
- if (replyto == NULLCHAR || strlen (replyto) == 1) {
- char *cp2;
-
- free (replyto);
- replyto = strdup (cp);
- cp2 = strchr (replyto, ' ');
- if (cp2)
- *cp2++ = 0;
- cp = cp2;
- } else /* point to 'to' user's parameter */
- cp = strchr (cp, ' ');
- cp = skipwhite (cp);
- }
- (void) getnext (cp, &put, here); /* allow ~c and ~# subs */
- if (strlen (put) == 1) {
- char *cp2;
-
- free (put);
- put = strdup (cp);
- cp2 = strchr (put, ' ');
- if (cp2)
- *cp2++ = 0;
- cp = cp2;
- } else
- cp = strchr (cp, ' ');
- cp = skipwhite (cp);
- lastresponse = 'n'; /* default to fails */
- /* get filename and open it */
- if (cp) { /* if filename given */
- FILE *out2;
-
- out2 = NULLFILE;
- if (stricmp (cp, "null"))
- out2 = fopen (cp, READ_TEXT);
- /* save current pos, and get tutor description */
- pos = ftell (here->fp);
- rewind (here->fp);
- (void) fgets (buf, 256, here->fp);
- fseek (here->fp, pos, SEEK_SET);
- cp = skipwhite (buf);
- rip (cp);
- /* now mail the file */
- (void) rdaemon (out2, replyto, NULLCHAR, put, cp, 'P', 0);
- lastresponse = 'y';
- if (out2 != NULLFILE)
- (void) fclose (out2);
- }
- free (put);
- break;
-
- case 'e': /* is io file at end of file */
- if (here->out != NULLFILE) {
- c = lastresponse = (feof (here->out)) ? 'y' : 'n';
- if (*cp && c == 'y')
- goto another;
- }
- break;
- case 's': /* seek to start of io file or sql query */
- #ifdef SQL
- if (tolower (*cp) == 'q') {
- /* sql query */
- cp = skipnonwhite (cp);
- cp = skipwhite (cp);
- expand_buf (cp, here);
- usflush (Curproc->output);
- (void) sql_query (cp);
- } else
- #endif
- if (here->out != NULLFILE) {
- switch (tolower (*cp)) {
- case 'e':
- fseek (here->out, 0L, 2);
- break;
- case 'p':
- cp = skipwhite (++cp);
- if (*cp) {
- k = *cp - '0';
- fseek (here->out, here->indexes[k], 0);
- break;
- } /* else, fall through */
- default:
- rewind (here->out);
- }
- }
- break;
- case 'u': /* upload a text file */
- if ((fp = fopen (cp, READ_TEXT)) != NULLFILE) {
- #ifndef STANDALONE
- (void) sendfile (fp, Curproc->output, ASCII_TYPE, 0);
- #else
- (void) sendfile (fp);
- #endif
- (void) fclose (fp);
- }
- break;
- case 'o': /* open an old io file */
- case 'f': /* create a new io file */
- if (here->out != NULLFILE)
- (void) fclose (here->out);
- here->out = NULLFILE;
- if (*cp == '~' && isdigit (cp[1]))
- cp = here->variables[cp[1] - '0'];
- here->out = fopen (cp, (c == 'f') ? CREATE_TEXT : UPDATE_TEXT);
- lastresponse = (here->out == NULLFILE) ? 'n' : 'y';
- break;
- case 'w': /* write a textline to the io file */
- if (here->out != NULLFILE)
- while (*cp) {
- cp = getnext (cp, &put, here);
- fprintf (here->out, put);
- free (put);
- cp++;
- }
- break;
- case 'r': /* read a line from io file in var */
- if (here->out != NULLFILE) {
- free (here->variables[k]);
- (void) fgets (buf, 256, here->out);
- rip (buf);
- here->variables[k] = strdup (buf);
- }
- break;
- case 'k': /* kill a file */
- unlink (cp);
- lastresponse = (access (cp, 0)) ? 'y' : 'n';
- break;
- case '?':
- switch (tolower (*cp)) {
- case 'c':
- lastresponse = (!here->color) ? 'n' : 'y';
- break;
- case 'i':
- lastresponse = (here->ipconnect) ? 'y' : 'n';
- break;
- default:
- break;
- }
- break;
- case '!':
- switch (tolower (*cp)) {
- case 'c':
- here->color = 1;
- break;
- default:
- break;
- }
- break;
- case '*':
- switch (tolower (*cp)) {
- case 'b':
- here->colorblock = 1;
- break;
- case 'e':
- here->colorblock = 0;
- break;
- default:
- break;
- }
- break;
- case '%':
- lastresponse = (!here->color) ? 'n' : 'y';
- if (here->color)
- colorfile (cp, here->last);
- break;
- case '@':
- mycolorchange (here, cp, here->last);
- break;
- case '$':{
- char *args[2];
- int lastback;
-
- lastback = here->goback;
- here->goback = 0;
- if (*cp == '$') {
- here->goback = 1;
- cp = skipwhite (++cp);
- }
- args[1] = cp;
- if (access (cp, 4))
- lastresponse = 'n';
- else {
- Curproc->output = here->socket[0];
- (void) doscript (0, args, here);
- lastresponse = 'y';
- Curproc->output = here->socket[0];
- }
- here->goback = lastback;
- }
- break;
- case ')':
- lastresponse = 'n';
- if (!k)
- sprintf (here->Error, "%scan't close stream 0", SCONFail2);
- else if (here->socket[k] <= 0)
- sprintf (here->Error, "%sstream %d not connected", SCONFail2, k);
- else {
- lastresponse = 'y';
- here->Error[0] = 0;
- if (socklen (here->socket[k], 0)) /* discard any remaining input */
- (void) recv_mbuf (here->socket[k], NULL, 0, NULLCHAR, 0);
- (void) shutdown (here->socket[k], 1);
- close_s (here->socket[k]);
- if (Curproc->output == here->socket[k]) {
- Curproc->output = here->socket[0];
- here->user = here->whichsocket = 0;
- }
- here->socket[k] = 0;
- }
- break;
- case '#':
- lastresponse = 'n';
- if (k && here->socket[k] < 0)
- sprintf (here->Error, "%sstream %d not connected", SCONFail, k);
- else {
- lastresponse = 'y';
- Curproc->output = here->socket[k];
- here->user = (k) ? here->socket[k] : 0;
- here->whichsocket = k;
- }
- break;
- case '(':
- lastresponse = 'n';
- if (here->socket[k])
- sprintf (here->Error, "%sstream %d already connected", SCONFail2, k);
- else {
- cp = skipnonwhite (cp);
- cp = skipwhite (cp);
- if ((here->socket[k] = cmdparse (sconcmds, cp, (void *) here)) != -1)
- lastresponse = 'y';
- else
- here->socket[k] = 0;
- }
- break;
- case '=':
- lastresponse = (here->socket[k] > 0) ? 'y' : 'n';
- break;
- case '^': /* convert string variable to upper/lower case */
- cp++;
- cp = skipwhite (cp);
- if (*cp == 'l')
- (void) strlwr (here->variables[k]);
- else if (*cp == 'u')
- (void) strupr (here->variables[k]);
- break;
- default:
- break;
- }
- }
- lost:
- if (here->out != NULLFILE) {
- (void) fclose (here->out);
- here->out = NULLFILE;
- }
- free (label);
- /* Curproc->output = here->socket[0]; */
- for (k = 0; k < 10; k++) {
- if (here->variables[k])
- if (!here->ischild || k < 5)
- free (here->variables[k]);
- #if 1
- if (disconexit && k && here->socket[k] > 0) { /* free connected streams */
- if (socklen (here->socket[k], 0)) /* discard any remaining input */
- (void) recv_mbuf (here->socket[k], NULL, 0, NULLCHAR, 0);
- (void) shutdown (here->socket[k], 1);
- close_s (here->socket[k]);
- here->socket[k] = 0;
- }
- #endif
- }
- here->user = 0;
- here->whichsocket = 0;
- }
-
-
-
- static const char *tutorialName[] = { "Learning Center", "Information Center", "News Center" };
- static const char banner[] = "For %s, connect to '%s' using the same path...\n";
-
-
-
- static void
- buildmenu (struct world *here)
- {
- FILE *fp;
- char buf[80], buf2[256], *cp, *cp2;
- struct ffblk ff;
-
- here->maxselect = 0;
- if (here->subdir)
- tprintf ("Current Sub-directory: %s\n\n", here->subdir);
- mycolorchange (here, "0F", here->last);
- tprintf ("\nWelcome to the ");
- mycolorchange (here, "0C", here->last);
- tprintf ("TNOS %s ", tutorialName[here->mode]);
- mycolorchange (here, "0F", here->last);
- tprintf ("at ");
- mycolorchange (here, "05", here->last);
- tprintf ("%s\n\n %c", Hostname, here->subdir ? 'E' : '0');
- mycolorchange (here, "07", here->last);
- tprintf (" - Exit %s\n", tutorialName[here->mode]);
- mycolorchange (here, "05", here->last);
- tprintf (" %c", (here->subdir) ? '0' : 'C');
- mycolorchange (here, "07", here->last);
- if (here->subdir)
- tputs (" - Return to Previous Menu\n");
- else
- tprintf (" - %sable ANSI Color Graphics\n", (here->color) ? "Dis" : "En");
- sprintf (buf, "%s/%s*.tut", (here->mode == 1) ? Info : (here->mode) ? News : Tutor, (here->subdir) ? here->subdir : "");
- if (findfirst (buf, &ff, 0) == 0) {
- do {
- kwait (NULL); /* Let others run */
- cp2 = strrchr (ff.ff_name, '.');
- if (cp2)
- *cp2 = '\0';
- sprintf (buf2, "%s/%s%s.tut", (here->mode == 1) ? Info : (here->mode) ? News : Tutor, (here->subdir) ? here->subdir : "", ff.ff_name);
- if ((fp = fopen (buf2, READ_TEXT)) != NULLFILE) {
- do {
- (void) fgets (buf2, 256, fp);
- cp = skipwhite (buf2);
- } while (*cp == '\n');
- (void) fclose (fp);
- if (*cp == '~') /* subdir directing file */
- cp = skipwhite (skipnonwhite (skipwhite (++cp)));
- here->Tutors[here->maxselect++] = strdup (ff.ff_name);
- mycolorchange (here, "05", here->last);
- tprintf (" %2d", here->maxselect);
- mycolorchange (here, "07", here->last);
- tprintf (" - %s", cp);
- }
- if (here->maxselect == 100)
- break;
- } while (findnext (&ff) == 0);
- }
- }
-
-
-
- #ifdef MSDOS
- #define SUBDIRSIZE 8
- #else
- #define SUBDIRSIZE 256
- #endif
-
-
-
- void
- #ifndef STANDALONE
- tutorserv (const char *call, struct mbx *m, int mode, int color, int ip)
- #else
- tutorserv (char *call, int mode, int color, int ip)
- #endif
- {
- char selection[SUBDIRSIZE + 2], filename[80], *cp;
- int k, sel, inited = 0;
- struct world here;
- #ifndef STANDALONE
- char tmp[AXBUF];
-
- Tutored++;
- #ifdef XSERVER
- xnotify (X_TUT);
- #endif
- #ifdef STATS_USE
- STATS_adduse (1);
- #endif
- #endif
- here.mode = mode;
- #ifndef STANDALONE
- Tutorlogins[here.mode]++;
- #endif
- here.maxselect = 0;
- here.call = call;
- #ifndef STANDALONE
- here.m = m;
- #endif
- here.subdir = NULLCHAR;
- #ifndef STANDALONE
- (void) sockblock (Curproc->output, SOCK_NOTXBLOCK); /* prevent backlogs ! */
- #endif
- here.color = (char) color;
- here.ipconnect = (char) ip;
- here.inescape = 0;
- here.ischild = 0;
- here.lostconnection = 0;
- here.Error[0] = 0;
- here.out = NULLFILE;
- here.whichsocket = here.background = 0;
- here.socket = callocw (10, sizeof (int));
-
- here.user = here.socket[0] = Curproc->output;
- filename[0] = 0;
- if (m && color)
- memcpy (here.last, m->colorset, 2);
- else
- here.last[0] = 0;
- for ( ; ; ) {
- if (inited)
- tprintf ("\n\n\n\n");
- else
- inited = 1;
- buildmenu (&here);
- do {
- mycolorchange (&here, "0F", here.last);
- tprintf ("\nEnter Selection:\n");
- mygets (selection, 10, &here);
- if (here.lostconnection)
- goto lost;
- kwait (NULL);
- if (toupper (*selection) == 'E') {
- free (here.subdir);
- here.subdir = NULLCHAR;
- sel = 0;
- break;
- }
- if (toupper (*selection) == 'C') {
- sel = -1;
- here.color ^= 1;
- break;
- }
- sel = atoi (selection);
- if (!sel)
- break;
- if (sel > here.maxselect)
- tprintf ("Invalid number... select 0 - %-d!\007\n", here.maxselect);
- } while (sel > here.maxselect);
- if (sel == -1)
- continue;
- if (sel)
- sprintf (filename, "%s/%s%s.tut", (here.mode == 1) ? Info : (here.mode) ? News : Tutor, (here.subdir) ? here.subdir : "", here.Tutors[sel - 1]);
- for (k = 0; k < here.maxselect; k++)
- free (here.Tutors[k]);
- if (!sel) {
- if (!here.subdir) /* not in a sub-directory! */
- break;
- here.subdir[strlen (here.subdir) - 1] = 0; /* take off last "/" */
- cp = strrchr (here.subdir, '/');
- if (!cp) {
- free (here.subdir);
- here.subdir = NULLCHAR;
- } else
- *(++cp) = 0;
- continue;
- }
- if (!*filename || (here.fp = fopen (filename, READ_TEXT)) == NULLFILE) {
- tprintf ("Sorry, but something seems to be wrong with that tutorial!\n");
- continue;
- }
- /* Let's check first line to see if this file describes a sub-directory */
- (void) fgets (filename, 80, here.fp);
- cp = filename;
- if (*cp == '~') { /* Yep! Sub-directory time! */
- cp = skipwhite (++cp);
- for (k = 0; k < SUBDIRSIZE && *cp && cp[k] != '\t' && cp[k] != ' '; k++)
- selection[k] = cp[k];
- selection[k++] = '/';
- selection[k] = 0;
- k += (int) ((here.subdir) ? strlen (here.subdir) : 0);
- cp = (char *) mallocw ((unsigned) ++k);
- *cp = 0;
- if (here.subdir)
- strcpy (cp, here.subdir);
- strcat (cp, selection);
- free (here.subdir);
- here.subdir = cp;
- } else {
- rewind (here.fp);
- for (k = 0; k < 10; k++) {
- here.variables[k] = NULLCHAR;
- here.indexes[k] = 0;
- here.socket[k] = 0;
- }
- process (&here);
- }
- (void) fclose (here.fp);
- }
- mycolorchange (&here, "09", here.last);
- tprintf ("\n\nThanks for using the ");
- mycolorchange (&here, "0C", here.last);
- tprintf ("TNOS %s ", tutorialName[here.mode]);
- mycolorchange (&here, "09", here.last);
- tprintf ("at ");
- mycolorchange (&here, "0E", here.last);
- tprintf ("%s\n\n", Hostname);
- mycolorchange (&here, "0F", here.last);
- if (m)
- mycolorchange (&here, m->colorset, here.last);
- #ifndef STANDALONE
- (void) pax25 (tmp, Tcall);
- if (*tmp && mode && Stutor != -1) /* if tutor server active, but not 'us */
- tprintf (banner, "tutorial assistance", tmp);
- (void) pax25 (tmp, Icall);
- if (*tmp && mode != 1 && Sinfo != -1) /* if info server active, but not 'us' */
- tprintf (banner, "local/area information", tmp);
- (void) pax25 (tmp, Ncall);
- if (*tmp && mode != 2 && Snews != -1) /* if news server active, but not 'us' */
- tprintf (banner, "Ham related NEWS", tmp);
- tputc ('\n');
- usflush (Curproc->output);
- (void) sockblock (Curproc->output, SOCK_BLOCK);
- free (here.socket);
- #endif
- lost:
- #ifndef STANDALONE
- Tutored--;
- #ifdef XSERVER
- xnotify (X_TUT);
- #endif
- #endif
- }
-
-
-
- extern char NoRead[];
- static short scriptmode = 0;
- static struct mbx *MbxCalling = NULLMBX;
- static short numCalling = 0;
- static char const **argsCalling;
- static short proxyServer = 0;
-
-
-
- static int
- scriptcmd (
- struct world *inherited, /* non-zero, inherited world */
- FILE *fp,
- const char *name
- ) {
- struct session *sp = NULLSESSION;
- int usesession = 0, k;
- struct world here;
-
- /* Use a session if this comes from console - WG7J*/
- if (!inMbScriptHook && !scriptmode && Curproc->input == Command->input) {
- usesession = 1;
- if ((sp = newsession (name, SCRIPT, 0)) == NULLSESSION) {
- return 1;
- }
- }
- inMbScriptHook = 0;
- here.background = scriptmode;
- if (!inherited || inherited == (struct world *) -1) {
- here.ischild = 0;
- here.user = 0;
- here.whichsocket = 0;
- here.ipconnect = 1;
- here.goback = 0;
- here.socket = callocw (10, sizeof (int));
-
- #ifndef STANDALONE
- if (inherited == (struct world *) -1) {
- here.m = MbxCalling;
- if (here.m)
- here.call = here.m->name;
- else
- here.call = "noname";
- MbxCalling = NULLMBX;
- } else {
- here.m = NULLMBX;
- #endif
- here.call = "noname";
- #ifndef STANDALONE
- }
- #endif
- for (k = 0; k < 10; k++) {
- here.indexes[k] = 0;
- here.variables[k] = NULLCHAR;
- }
- if (inherited == (struct world *) -1) {
- for (k = 0; k < numCalling; k++)
- here.variables[k] = strdup (argsCalling[k]);
- here.indexes[0] = numCalling;
- inherited = 0;
- if (proxyServer)
- here.goback = proxyServer;
- proxyServer = 0;
- }
- } else {
- here.ischild = 1;
- here.user = inherited->user;
- here.whichsocket = inherited->whichsocket;
- here.ipconnect = inherited->ipconnect;
- here.goback = inherited->goback;
- here.socket = inherited->socket;
- here.call = inherited->call;
- if (inherited->background)
- here.background = inherited->background;
- #ifndef STANDALONE
- here.m = inherited->m;
- #endif
- for (k = 0; k < 10; k++) {
- here.indexes[k] = inherited->indexes[k];
- if (inherited->variables[k])
- here.variables[k] = strdup (inherited->variables[k]);
- else
- here.variables[k] = NULLCHAR;
- }
- }
- here.fp = fp;
- here.mode = 0;
- here.maxselect = 0;
- here.subdir = NULLCHAR;
- here.color = 0;
- here.lostconnection = 0;
- here.out = NULLFILE;
- here.inescape = 0;
- here.last[0] = 0;
- here.Error[0] = 0;
- process (&here);
- (void) fclose (here.fp);
- if (inherited) {
- for (k = 5; k < 10; k++) {
- if (!here.goback) {
- if (inherited->variables[k])
- free (inherited->variables[k]);
- inherited->variables[k] = NULLCHAR;
- if (here.variables[k])
- inherited->variables[k] = here.variables[k];
- inherited->indexes[k] = here.indexes[k];
- } else
- free (here.variables[k]);
- }
- if (!here.goback)
- inherited->whichsocket = here.whichsocket;
- } else
- free (here.socket);
- if (usesession) {
- (void) keywait (NULLCHAR, 1);
- freesession (sp);
- }
- return 0;
- }
-
-
-
- int
- doscript (int argc, char *argv[], void *p)
- {
- FILE *fp;
- int oldin, oldout;
- int thisscriptmode;
-
- {
- char fname[256];
-
- strncpy (fname, make_fname (Command->curdirs->dir, argv[1]), 256);
- if ((fp = fopen (fname, READ_TEXT)) == NULLFILE) {
- tprintf (NoRead, fname, SYS_ERRLIST(errno));
- return 1;
- }
- }
-
- scriptmode = (argc > 2 && !strnicmp (argv[2], "back", 4)) ? 1 :
- (!argc && ((struct world *) p)->goback) ? 1 : 0;
- oldin = Curproc->input;
- oldout = Curproc->output;
- if (scriptmode)
- Curproc->input = Curproc->output = -1;
- thisscriptmode = scriptmode;
- if (!inMbScriptHook && (scriptmode || Curproc->input == Command->input))
- (void) newproc ("script", 2048, (void (*)(int, void *, void *)) scriptcmd, (argc > 1) ? 0 : (int) p, (void *) fp, (void *) strdup (argv[1]), 2);
- else
- (void) scriptcmd ((argc > 1) ? 0 : (struct world *) p, fp, argv[1]);
-
- if (thisscriptmode) {
- Curproc->input = oldin;
- Curproc->output = oldout;
- }
- return 0;
- }
-
-
-
-
- #ifndef STANDALONE
- int
- dombscript (int argc, char *argv[], void *p)
- {
- struct mbx *m;
- char *args[2], buffer[128];
-
- m = (struct mbx *) p;
- if (argc == 1) {
- /* listing of commands available */
- (void) DisplayFile (UCmdsHelp, m->user);
- return 0;
- }
- sprintf (buffer, "%s/%s.cmd", UserCmds, argv[1]);
- if (!access (buffer, 4)) {
- args[1] = buffer;
- numCalling = (short int) (argc - 2);
- if (numCalling > 10)
- numCalling = 10;
- argsCalling = (char const **) &argv[2];
- MbxCalling = m;
- (void) doscript (1, args, (void *) -1);
- } else {
- tprintf ("Unknown CMD: '%s'\n", argv[1]);
- (void) DisplayFile (UCmdsHelp, m->user);
- }
- return 0;
- }
-
-
-
- void
- mbscripthook (struct mbx *m, const char *hookfile)
- {
- char *args[2], buffer[128];
- char *args2[2];
-
- sprintf (buffer, "%s/%s", UserCmds, hookfile);
- if (!access (buffer, 4)) {
- args[1] = buffer;
- numCalling = 1;
- args2[0] = m->line;
- argsCalling = (char const **) &args2[0]; /*lint !e789 */
- MbxCalling = m;
- inMbScriptHook = 1;
- (void) doscript (1, args, (void *) -1);
- }
- }
-
-
-
- int
- proxy (FILE *fp, const char *from OPTIONAL)
- {
- char buf[512], subject[256], realfrom[128], *cp;
- long startat;
- FILE *out;
- char const *args[2];
- int oldin, oldout;
- int skiptoblank = 0;
-
- parseheader (fp, realfrom, subject, NULLCHAR, NULLCHAR, buf, &startat);
- cp = strchr (realfrom, '@');
- if (cp)
- *cp = 0;
- sprintf (buf, "%s/proxy.tmp", Spool);
- out = fopen (buf, "w");
- if (out == NULLFILE)
- return 1;
- fprintf (out, "[%s]\n", realfrom);
- fseek (fp, startat, SEEK_SET);
- while (fgets (buf, 512, fp) != NULLCHAR) {
- if (!strncmp ("Message-Id: ", buf, 12))
- skiptoblank = 1;
- else {
- if (skiptoblank && buf[0] == '\n')
- skiptoblank = 0;
- else if (!skiptoblank)
- fputs (buf, out);
- }
- }
- (void) fclose (out);
- numCalling = 1;
- argsCalling = args; /*lint !e789 */
- args[0] = "import";
-
- sprintf (buf, "%s/proxy.cmd", UserCmds);
- if ((out = fopen (buf, READ_TEXT)) == NULLFILE)
- return 1;
-
- oldin = Curproc->input;
- oldout = Curproc->output;
- Curproc->input = Curproc->output = -1;
- scriptmode = 1;
- proxyServer = 1;
-
- #if 0
- newproc ("script", 2048, (void (*)(int, void *, void *)) scriptcmd, (int) -1, (void *) out, (void *) strdup ("Proxy"), 2);
- #else
- (void) scriptcmd ((struct world *) -1, out, "Proxy");
- #endif
- Curproc->input = oldin;
- Curproc->output = oldout;
- return 1;
- }
- #endif
-
-
- #endif
-